home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / szml2src.zip / SIZML200.C < prev   
C/C++ Source or Header  |  1991-01-01  |  20KB  |  595 lines

  1. /****************************************************************************
  2. * Sizml200.c - 12/31/90                                                     *
  3. *                                                                           *
  4. * Sizml200 is based on the original work of Bob Hartman. Portions of this   *
  5. * program are (C) Copyright 1990-91 Bill Weinel and may not be modified or  *
  6. * distributed (except as originally provided) without my expressed written  *
  7. * permission. Sizml200 MUST BE distributed FREE OF CHARGE and unmodified as *
  8. * originally provided. It may not be offered for sale in any shape or form  *
  9. * as part of any package or of program collection.                          *
  10. *                                                                           *
  11. * The original Sizml200.Lzh package was compiled with MS Quick C v2.00.     *
  12. * Due to stack space limitations compile with QCL only (except for DEBUG).  *
  13. * QCL compile command used to make Sizml200:                                *
  14. *                                                                           *
  15. *       QCL /AC /Gt256 /F 6000 /Ot sizml200.c                               *
  16. *                                                                           *
  17. * Possible future enhancements:                                             *
  18. *   - using the heap for struct & variable storage to cut stack space usage *
  19. *   - cleaning up and repetitive sections into functions.                   *
  20. *                                                                           *
  21. ****************************************************************************/
  22.  
  23. /* Include headers */
  24.  
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <dos.h>
  28. #include <fcntl.h>
  29. #include <sys\types.h>
  30. #include <sys\stat.h>
  31. #include <io.h>
  32. #include <stdlib.h>
  33.  
  34.  
  35. /* If debugging is necessary.. you may uncomment this to test with small */
  36. /* file sets. (ie: 10 nodes or less). This allows testing with the QCE /*
  37.  
  38. /* #define  DEBUGS */     /* trims size of buffers, nodes for debug */
  39.  
  40. /* Global variables & structs */
  41.  
  42. typedef struct {
  43.    int zone;              /* zone number */
  44.    int net;               /* net number */
  45.    int node;              /* node number */
  46.    long size;             /* packet size */
  47.    char hold[80];         /* hold area */
  48. } NODELIST, *NODELISTP;
  49.  
  50. #ifdef DEBUGS
  51. NODELIST nodes[10];             /* small list for testing */
  52. #else
  53. NODELIST nodes[500];            /* allow for 500 nodes */
  54. #endif
  55. int n_nodes;
  56.  
  57. char drive1[_MAX_DRIVE];
  58. char dir1[_MAX_DIR];
  59. char fname1[_MAX_FNAME];
  60. char ext1[_MAX_EXT];
  61. char drive2[_MAX_DRIVE];
  62. char dir2[_MAX_DIR];
  63. char fname2[_MAX_FNAME];
  64. char ext2[_MAX_EXT];
  65.  
  66. char cfg_file[100];          /* user defined cfg file name */
  67. char qflag_file[100];        /* used for qm multitaking flags */
  68. char move_name[100];         /* move area name */
  69. char outbound_name[100];     /* old outbound area name */
  70. char outbnd_name[100];       /* new outbound area name */
  71. char hold_name[100];
  72. char temp_name[100];
  73. char flo1_name[100];
  74. char flo2_name[100];
  75. char test_name[100];         /* drive test name */
  76. char bflag_name[100];        /* binkley flag path */
  77. char send_files[100][100];
  78. int myzone = -1000;
  79. int mynet = -1000;
  80. int mynode = -1000;
  81.  
  82. char *REV = "$Revision: 2.00 $";                /* Sizemail revision number */
  83.  
  84. char   *str_to_upper(char *p)                   /* convert a string to upper */
  85. {
  86.     char *pt;                               /* temp head pointer */
  87.  
  88.     pt = p;                                 /* save head pointer */
  89.     if (p != NULL)                          /* if valid.. convert */
  90.      {
  91.      for(; *p != '\0'; p++)
  92.       *p = toupper(*p);
  93.      return(pt);
  94.      }
  95.     else                                    /* otherwise.. return */
  96.      return (NULL);
  97. }
  98.  
  99. void    main (int argc, char *argv[])
  100. {
  101.    int    i, j, k, length, f1, fi, fo;
  102.    int    done = 0;                             /* ?lo done flag */
  103.    int    done_node = 0;                        /* node done flag */
  104.    int    move_flag = 0;                        /* move|copy flag */
  105.    int    usr_cfg = 0;                          /* user cfg file */
  106.    int    flags = 0;                            /* flag file mode */
  107.    int    all = 0;                              /* all files mode */
  108.    int    multtsk = 0;                          /* multitask mode */
  109.    int    inf_level = 2;                        /* info level default*/
  110.    int    ndflag = 0;                           /* node hdr display flag */
  111.    int    idflag = 0;                           /* indent display flag */
  112.    char   infolev[2];                           /* info level cmd */
  113.    char   buff[256];                            /* cfg file buffer */
  114.    char   *p, *p1, *p2, *p3, *p4, *p5, *p6;     /* string pointers */
  115.    char   buff1[20], buff2[20];                 /* Junk buffers */
  116.    FILE   *f;
  117.    struct find_t abuffer, fbuffer, qflbuffer, bflbuffer;
  118.  
  119. #ifdef  DEBUGS
  120.    char   dskbuf[256];                          /* test file copy buffer */
  121. #else
  122.    char   dskbuf[16392];                        /* file copy buffer */
  123. #endif
  124.  
  125.    sscanf (REV, "$%s %s", buff1, buff2);
  126.    printf ("\nSizeMail - %s %s  %s %s\n", buff1, buff2, __DATE__, __TIME__);
  127.    printf ("             original code by Bob Hartman, Bit Bucket Software\n");
  128.    printf ("             updated by Bill Weinel of 1:151/121@Fidonet.org\n");
  129.    printf ("             portions (C) Copyright 1990-91 Bill Weinel\n\n");
  130.  
  131.  
  132.    /* parse command line */
  133.    i=0;
  134.    while ((i+1) != argc)
  135.    {
  136.    i++;
  137.    if (strcmp(argv[i],"?") == 0)                /* show help */
  138.       {
  139.       printf ("\n Usage: Sizemail [-cuser.cfg] [-fflags.dir] [-b] [-vx] [-a] [?]\n\n");
  140.       printf (" where:\n");
  141.       printf ("        -cuser.cfg is a user defined cfg file\n");
  142.       printf ("         (if not specified defaults to SIZEMAIL.CFG)\n");
  143.       printf ("        -fflags.dir uses QM multitasking flag directory\n");
  144.       printf ("        -b uses Binkley multitasking mode\n");
  145.       printf ("        -vx is verbose level\n");
  146.       printf ("          where x is:\n");
  147.       printf ("           0 - nothing displayed\n");
  148.       printf ("           1 - only significant processing displayed\n");
  149.       printf ("           2 - all processing displayed\n");
  150.       printf ("        -a is move all mode\n");
  151.       printf ("         ? displays help\n\n");
  152.       exit(0);
  153.       }
  154.    else if (strncmp(argv[i],"-a",2) == 0)       /* set move all mode */
  155.       {
  156.       all = 1;
  157.       }
  158.    else if (strncmp(argv[i],"-b",2) == 0)       /* set multitask mode */
  159.       {
  160.       multtsk = 1;
  161.       }
  162.    else if (strncmp(argv[i],"-v",2) == 0)       /* set verbose level */
  163.       {
  164.       p = strpbrk(argv[i],"v") + 1;
  165.       strcpy(infolev, p);                       /* get verbosity level */
  166.       switch (infolev[0])                       /* convert it to a flag */
  167.        {
  168.        case '0': inf_level = 0;
  169.         break;
  170.        case '1': inf_level = 1;
  171.         break;
  172.        case '2': inf_level = 2;
  173.         break;
  174.        default: inf_level = 2;                  /* default level */
  175.        }
  176.       }
  177.    else if (strncmp(argv[i],"-f",2) == 0)       /* set flagged mode */
  178.       {
  179.       flags = 1;
  180.       p = strpbrk(argv[i],"f") + 1;
  181.       strcpy(qflag_file, str_to_upper(p));      /* get user flags dir name */
  182.       }
  183.    else if (strncmp(argv[i],"-c",2) == 0)       /* read specified cfg file */
  184.       {
  185.       usr_cfg = 1;                              /* set user defined cfg flag */
  186.       p = strpbrk(argv[i],"c") + 1;
  187.       strcpy(cfg_file, str_to_upper(p));        /* get user cfg file name */
  188.       }
  189.    } /* end while */
  190.  
  191.    if (!usr_cfg)        /* did we have a user defined cfg? */
  192.     {                   /* no use default */
  193.     if ((f = fopen ("SIZEMAIL.CFG", "r")) == NULL)
  194.       {
  195.       printf ("Error: Cannot open SizeMail.Cfg - aborting\n");
  196.       exit (1);
  197.       }
  198.     }                   /* yep go get it */
  199.     else if ((f = fopen (cfg_file, "r")) == NULL)
  200.       {
  201.       printf ("Error: Cannot open %s - aborting\n", cfg_file);
  202.       exit (1);
  203.       }
  204.             /* read & parse cfg file */
  205.    while (str_to_upper(fgets (buff, 256, f)) != NULL)
  206.       {
  207.       if (strnicmp (buff, "NODE", 4) == 0)
  208.          {
  209.      sscanf (&buff[4], "%d:%d/%d", &myzone, &mynet, &mynode);
  210.          }
  211.       else if (strnicmp (buff, "OUTBOUND", 8) == 0)
  212.      {
  213.      sscanf (&buff[8], "%s", outbound_name);
  214.      strcpy (outbnd_name, outbound_name);   /* save for later */
  215.      strcpy (temp_name, outbound_name);
  216.      strcpy (flo1_name, outbound_name);
  217.      strcpy (flo2_name, outbound_name);
  218.      strcpy (bflag_name, outbound_name);
  219.                         /* point to end of each string */
  220.      p = &(outbound_name[strlen(outbound_name)]);
  221.      p2 = &(temp_name[strlen(temp_name)]);
  222.      p3 = &(flo1_name[strlen(flo1_name)]);
  223.      p4 = &(flo2_name[strlen(flo2_name)]);
  224.      p5 = &(qflag_file[strlen(qflag_file)]);
  225.      p6 = &(bflag_name[strlen(bflag_name)]);
  226.      }
  227.       else if (strnicmp (buff, "SIZE", 4) == 0)
  228.      {
  229.      sscanf (&buff[4], "%d:%d/%d %ld %s", &(nodes[n_nodes].zone),
  230.                                        &(nodes[n_nodes].net),
  231.                                        &(nodes[n_nodes].node),
  232.                        &(nodes[n_nodes].size),
  233.                        (nodes[n_nodes].hold));
  234.          ++n_nodes;
  235.          }
  236.       }
  237.    fclose (f);
  238.  
  239.    /* weed out the bad errors first */
  240.    if ((myzone == -1000) || (mynet == -1000) || (mynode == -1000))
  241.       {
  242.       printf ("Error: No valid zone:net/node number for this node - aborting\n");
  243.       exit (1);
  244.       }
  245.  
  246.    if (outbound_name[0] == '\0')
  247.       {
  248.       printf ("Error: No outbound area defined for this node - aborting\n");
  249.       exit (1);
  250.       }
  251.  
  252.    /* Run through each zone:net/node to find arcmail file */
  253.  
  254.    for (i = 0; i < n_nodes; i++)
  255.       {
  256.       ndflag = 0;                               /* reset nd hdr display flag */
  257.       idflag = 0;                               /* reset indent flag */
  258.  
  259.       if (inf_level >= 2)
  260.        {
  261.        ndflag = 1;                              /* show we displayed it */
  262.        printf ("Node %d:%d/%d", nodes[i].zone, nodes[i].net, nodes[i].node);
  263.        }
  264.  
  265.       if (myzone != nodes[i].zone)              /* point to outbound */
  266.          {
  267.          sprintf (p, ".%03d\\%04x%04x.*", nodes[i].zone,
  268.             mynet - nodes[i].net, mynode - nodes[i].node);
  269.      if (multtsk)                           /* setup binkley flag pointer */
  270.       sprintf (p6, ".%03d\\%04x%04x.BSY", nodes[i].zone,
  271.         nodes[i].net, nodes[i].node);
  272.      }
  273.       else
  274.          {
  275.          sprintf (p, "\\%04x%04x.*",
  276.             mynet - nodes[i].net, mynode - nodes[i].node);
  277.      if (multtsk)                           /* setup binkley flag pointer */
  278.       sprintf (p6, "\\%04x%04x.BSY", nodes[i].net, nodes[i].node);
  279.          }
  280.  
  281.       /* If file doesn't exist, just continue */
  282.       if (_dos_findfirst (outbound_name, _A_NORMAL, &abuffer))
  283.          {
  284.      if (inf_level >= 2)
  285.       printf ("\t-None found\n");           /* terminate line and continue */
  286.      continue;
  287.          }
  288.  
  289.  
  290.      done_node = 0;     /* else set up loop to check for a nodes files */
  291.      while (!done_node)
  292.       {
  293.  
  294.       /* if we need to adjust line starting point */
  295.       if ((inf_level >= 1) && (idflag == 1))
  296.        {
  297.        printf ("             ");
  298.        }
  299.  
  300.       /* If size of file is less than threshold, continue */
  301.       if ((abuffer.size < nodes[i].size) && (!all))
  302.          {
  303.      if (inf_level >= 2)
  304.       {
  305.       printf ("\t-Leaving mail of size %ld < %ld threshold\n", abuffer.size, nodes[i].size);
  306.       idflag = 1;   /* if there's more than one, we need to indent */
  307.       }
  308.      /* get the next file for this node number */
  309.      if (_dos_findnext (&abuffer))
  310.         {
  311.         /* if we indented we need to adjust line starting point */
  312.         if ((inf_level >= 1) && (idflag == 1))
  313.          printf ("\r");
  314.         done_node = 1;
  315.         }
  316.      continue;                              /* then drop to loop */
  317.          }
  318.  
  319.       /* if file size is 0 and move all is set.. don't move */
  320.       if ((abuffer.size < 1) && (all))
  321.      {
  322.      if (inf_level >= 2)
  323.       {
  324.       printf ("\t-Leaving mail of size %ld\n", abuffer.size);
  325.       idflag = 1;   /* if there's more than one, we need to indent */
  326.       }
  327.      /* get the next file for this node number */
  328.      if (_dos_findnext (&abuffer))
  329.         {
  330.         /* if we indented we need to adjust line starting point */
  331.         if ((inf_level >= 1) && (idflag == 1))
  332.          printf ("\r");
  333.         done_node = 1;
  334.         }
  335.      continue;                              /* then drop to loop */
  336.      }
  337.  
  338.      /* Check to see if a Flag file exists for node */
  339.      /* If so, then do not change their mail */
  340.      /* otherwise, create file, then delete it after processing */
  341.  
  342.      if (flags)  /* do QM style multitasking check */
  343.       {
  344.  
  345.       sprintf (p5, "\\%04x%04x.%03x", nodes[i].net,
  346.      nodes[i].node, nodes[i].zone);
  347.  
  348.       if (_dos_findfirst (qflag_file, _A_NORMAL, &qflbuffer) == 0)  /* Found it */
  349.        {
  350.        if (inf_level >= 2)
  351.     printf ("\t-QM is currently processing mail - NOT MOVING!\n");
  352.        done_node = 1;
  353.        continue;                                /* drop to loop */
  354.        }
  355.  
  356.     /* Create the Flag file */
  357.     /* BEGIN CRITICAL QM CODE SECTION */
  358.  
  359.       if ((f = fopen (qflag_file, "ab")) != NULL)
  360.        {
  361.        fclose (f);
  362.        }
  363.       } /* end if flags */
  364.  
  365.      /* Check to see if a Binkley style flag file exists for node */
  366.      /* If so, then do not change their mail */
  367.      /* otherwise, create file, then delete it after processing */
  368.  
  369.      if (multtsk)
  370.       {
  371.       if (_dos_findfirst (bflag_name, _A_NORMAL, &bflbuffer) == 0)  /* Found it */
  372.        {
  373.        if (inf_level >= 2)
  374.     printf ("\t-Binkley currently processing mail - NOT MOVING!\n");
  375.        done_node = 1;
  376.        continue;                                /* drop to loop */
  377.        }
  378.  
  379.     /* Create the Binkley flag file */
  380.     /* BEGIN CRITICAL BINKLEY CODE SECTION */
  381.  
  382.       if ((f = fopen (bflag_name, "ab")) != NULL)
  383.        {
  384.        fclose (f);
  385.        }
  386.       } /* end if mttsk */
  387.  
  388.       if ((inf_level >= 1) && (!ndflag))
  389.        {
  390.        ndflag = 1;
  391.        printf ("Node %d:%d/%d", nodes[i].zone, nodes[i].net, nodes[i].node);
  392.        }
  393.  
  394.       /* determine where we are going to save it */
  395.       strcpy(test_name, nodes[i].hold);         /* get name to test */
  396.       if ((strlen(nodes[i].hold) >= 2) &&
  397.       (strncmp(outbnd_name, test_name, 2)) != 0)
  398.        {
  399.        move_flag = 1;                           /* show we are copying */
  400.        strcpy(hold_name, nodes[i].hold);
  401.        }
  402.       else if (nodes[i].hold[0] == '\0')
  403.         {
  404.         move_flag = 0;
  405.         strcpy (hold_name, outbnd_name);
  406.         }
  407.        else
  408.         {
  409.         move_flag = 0;                      /* show we are renaming */
  410.         strcpy (hold_name, outbnd_name);
  411.         }
  412.  
  413.       p1 = &(hold_name[strlen(hold_name)]);
  414.       sprintf (p1, ".TMP");
  415.       mkdir (hold_name);
  416.  
  417.       /* Create hold area name */
  418.       sprintf (p1, ".TMP\\%s", abuffer.name);
  419.  
  420.       /* Create actual file name */
  421.       if (myzone != nodes[i].zone)
  422.          {
  423.      sprintf (p2, ".%03d\\%s", nodes[i].zone, abuffer.name);
  424.          sprintf (p3, ".%03d\\%04x%04x.?LO", nodes[i].zone, nodes[i].net, nodes[i].node);
  425.          }
  426.       else
  427.          {
  428.      sprintf (p2, "\\%s", abuffer.name);
  429.          sprintf (p3, "\\%04x%04x.?LO", nodes[i].net, nodes[i].node);
  430.          }
  431.  
  432.       /* Move or copy file to holding area */
  433.  
  434.       if (move_flag)
  435.       {
  436.        if (inf_level >= 1)                      /* display area name */
  437.     {
  438.     printf ("\t-Copying %s [%ldb] -> %s\n", (p+1), abuffer.size, hold_name);
  439.     idflag = 1;     /* ok to indent */
  440.     }
  441.  
  442.        /* Open input file for read */
  443.        if ((fi = open (temp_name, O_BINARY|O_RDONLY, S_IREAD)) == -1)
  444.     {
  445.     printf ("\nError: Cannot open %s - aborting\n", temp_name);
  446.     if (multtsk) unlink (bflag_name);
  447.     if (flags) unlink (qflag_file);
  448.     exit (1);
  449.     }
  450.  
  451.        /* Open output file for write */
  452.        if ((fo = open (hold_name, O_CREAT|O_WRONLY|O_BINARY, S_IWRITE)) == -1)
  453.     {
  454.     printf ("\nError: Cannot open %s - aborting\n", hold_name);
  455.     if (multtsk) unlink (bflag_name);
  456.     if (flags) unlink (qflag_file);
  457.     exit (1);
  458.     }
  459.  
  460. #ifdef DEBUGS
  461.        while (length = read (fi, dskbuf, 256))   /* small tst buf copy */
  462. #else
  463.        while (length = read (fi, dskbuf, 16392)) /* production copy */
  464. #endif
  465.     {
  466.     if ((write (fo, dskbuf, length)) == -1)
  467.      {
  468.      printf ("\nError: Cannot write %s - aborting\n", hold_name);
  469.      if (multtsk) unlink (bflag_name);
  470.      if (flags) unlink (qflag_file);
  471.      exit(1);
  472.      }
  473.     }
  474.  
  475.        if (close (fi) == -1)
  476.     {
  477.     printf ("\nError: Cannot close %s - aborting\n", temp_name);
  478.     if (multtsk) unlink (bflag_name);
  479.     if (flags) unlink (qflag_file);
  480.     exit(1);
  481.     }
  482.  
  483.        if (close (fo) == -1)
  484.     {
  485.     printf ("\nError: Cannot close %s - aborting\n", hold_name);
  486.     if (multtsk) unlink (bflag_name);
  487.     if (flags) unlink (qflag_file);
  488.     exit(1);
  489.     }
  490.  
  491.        remove (temp_name);                      /* delete original file */
  492.       }
  493.       else                                      /* we can just rename */
  494.       {
  495.        remove (hold_name);                      /* be sure to zap filename first */
  496.        if (rename (temp_name, hold_name))
  497.     {
  498.     printf ("\nError: Cannot rename %s - aborting\n", temp_name);
  499.     if (multtsk) unlink (bflag_name);
  500.     if (flags) unlink (qflag_file);
  501.     exit(1);
  502.     }
  503.       if (inf_level >= 1)                       /* display area name */
  504.        {
  505.        printf ("\t-Moving %s [%ldb] -> %s\n", (p+1), abuffer.size, hold_name);
  506.        idflag = 1; /* ok to indent */
  507.        }
  508.       }
  509.  
  510.       /* Create a 0 length file by the same name */
  511.       f1 = open (temp_name, O_CREAT|O_TRUNC|O_BINARY|O_RDWR, S_IWRITE);
  512.       close (f1);
  513.  
  514.       /* Edit .?LO file to change # to ^ */
  515.       if (_dos_findfirst (flo1_name, _A_NORMAL, &fbuffer))
  516.      {
  517.      printf ("\nError: Could not find .FLO file for %d:%d/%d - continuing\n",
  518.         nodes[i].zone, nodes[i].net, nodes[i].node);
  519.     if (multtsk) unlink (bflag_name);
  520.     if (flags) unlink (qflag_file);
  521.      }
  522.       else
  523.      {                                      /* process them til finished */
  524.      done = 0;
  525.      while (!done)
  526.         {
  527.         if (fbuffer.size > 0)
  528.            {
  529.            if (myzone != nodes[i].zone)
  530.           sprintf (p4, ".%03d\\%s", nodes[i].zone, fbuffer.name);
  531.            else
  532.           sprintf (p4, "\\%s", fbuffer.name);
  533.            if ((f = fopen (flo2_name, "r")) != NULL)
  534.           {
  535.           j = 0;
  536.           while (fgets (send_files[j], 100, f) != NULL)
  537.              {
  538.              if ((send_files[j][0] == '\n') ||
  539.              (send_files[j][0] == '\r') ||
  540.              (send_files[j][0] == '\0'))
  541.             {
  542.             continue;
  543.             }
  544.  
  545.              if (send_files[j][0] == '#')
  546.             {
  547.             _splitpath (&(send_files[j][1]), drive1, dir1, fname1, ext1);
  548.             _splitpath (temp_name, drive2, dir2, fname2, ext2);
  549.             if ((stricmp (fname1, fname2) == 0) &&
  550.                 (stricmp (ext1, ext2) == 0))
  551.                {
  552.                strcpy (&(send_files[j][1]), hold_name);
  553.                send_files[j][0] = '^';
  554.                strcat (send_files[j], "\n");
  555.                }
  556.             }
  557.  
  558.              ++j;
  559.              }
  560.  
  561.           fclose (f);
  562.  
  563.           unlink (flo2_name);
  564.  
  565.           f = fopen (flo2_name, "w");
  566.           for (k = 0; k < j; k++)
  567.              {
  568.              fputs (send_files[k], f);
  569.              }
  570.           fclose (f);
  571.           }
  572.            }
  573.  
  574.         if (_dos_findnext (&fbuffer))
  575.            done = 1;
  576.         }
  577.      }
  578.  
  579.        if (multtsk) unlink (bflag_name);        /* delete the busy flags */
  580.        if (flags) unlink (qflag_file);
  581.  
  582.        /* check the next file for that node number */
  583.        if (_dos_findnext (&abuffer))
  584.      {
  585.      /* if we indented we need to adjust line starting point */
  586.      if ((inf_level >= 1) && (idflag == 1))
  587.       printf ("\r");
  588.      done_node = 1;
  589.      }
  590.  
  591.        }  /* while (!done_node) */
  592.  
  593.       }  /* for */
  594. }
  595.